package org.bing.zion.core;

import java.io.IOException;
import java.nio.ByteBuffer;

import org.bing.engine.common.logging.Log;
import org.bing.engine.common.logging.LogFactory;


class ProtocolFilterWrapper extends ProtocolFilterChain implements ProtocolFilter {
	protected static final Log logger = LogFactory.getLog(ProtocolFilterWrapper.class);
	private ProtocolFilterChain realChain;
	private ProtocolFilterWrapper nextWrapper;
	private ProtocolFilter nextNull;
	private ProtocolFilterWrapper prevWrapper;
	private ProtocolFilter prevNull;
	private ProtocolFilter realFilter;

	public ProtocolFilterWrapper(ProtocolFilterChain chain, ProtocolFilter filter) {
		this.realChain = chain;
		this.realFilter = filter;
	}

	public void setNextWrapper(ProtocolFilterWrapper next) {
		this.nextWrapper = next;
	}

	public void setPrevWrapper(ProtocolFilterWrapper prev) {
		this.prevWrapper = prev;
	}

	public void messageReceived(ProtocolFilterChain chain, Session session, Object msg) throws IOException {
		realFilter.messageReceived(this, session, msg);
	}

	public void messageSent(ProtocolFilterChain chain, Session session, Object msg) throws IOException {
		realFilter.messageSent(this, session, msg);
	}

	@Override
	public ProtocolFilter next() {
		if (nextWrapper != null) {
			return nextWrapper;
		} else {
			if (nextNull == null) {
				nextNull = new ProtocolFilterAdapter() {
					@Override
					public void messageReceived(ProtocolFilterChain chain, Session session, Object msg) {
						realChain.dispatch(session, msg);
					}
				};
			}
			return nextNull;
		}
	}

	@Override
	public ProtocolFilter prev() {
		if (prevWrapper != null) {
			return prevWrapper;
		} else {
			if (prevNull == null) {
				prevNull = new ProtocolFilterAdapter() {
					@Override
					public void messageSent(ProtocolFilterChain chain, Session session, Object msg) {
						if (msg instanceof ByteBuffer) {
							realChain.flush(session, (ByteBuffer) msg);
						} else {
							logger.error("Error final type,should be ByteBuffer! " + msg);
						}
					}
				};
			}
			return prevNull;
		}
	}

}
